const express = require('express');
const path = require('path');

const lessMiddleware = require('less-middleware');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const favicon = require('serve-favicon');
const compression = require('compression'); // Gzip 压缩(生产环境中的大流量网站，实施压缩的最佳位置是在反向代理层级)
const helmet = require('helmet'); // 适当地设置 HTTP 头
const methodOverride = require('method-override');

// const mongoStore = require('connect-mongo')(session);
// const flash = require('connect-flash');
// const winston = require('winston');
// const helpers = require('view-helpers');
// const csrf = require('csurf');
// const cors = require('cors');
// const ultimatePagination = require('ultimate-pagination');
// const pkg = require('../package.json');
// const requireHttps = require('../middlewares/require-https');
// const env = process.env.NODE_ENV || 'development';

/**
 * Expose routes
 */
module.exports = (app, passport) => {
  // app.set('env', false ? 'development' : 'production');
  app.set('env', process.env.NODE_ENV || 'production');
  // console.log(1, process.env.NODE_ENV);
  // console.log(2, app.get('env'));

  // 给所有请求的res注入res.locals.user默认值
  app.use((req, res, next) => {
    res.locals.user = 'No token';
    next();
  });

  /**
   * 通過設置各種HTTP標頭來幫助您保護Express應用程序 (至少禁用 X-Powered-By 头是必须的)
   * https://www.npmjs.com/package/helmet
   */
  app.use(helmet());
  app.use(
    /**
     * 覆盖helmet.contentSecurityPolicy
     * node_modules\helmet\dist\middlewares\content-security-policy\index.js
     *
     * http://www.ruanyifeng.com/blog/2016/09/csp.html
     * https://www.cnblogs.com/aeolian/p/11083804.html
     */
    helmet.contentSecurityPolicy({
      directives: {
        ...helmet.contentSecurityPolicy.getDefaultDirectives(),
        'script-src': ["'self'", "'unsafe-inline'", 'https://cdn.bootcdn.net', "'nonce-TmV2ZXIgZ29pb2mc2gdG8gZ2l2ZSB5b3UgdXA='"],
        // 'script-src-attr': ["'self'", "'nonce-TmV2ZXIgZ29pb2mc2gdG8gZ2l2ZSB5b3UgdXA='"],
        // scriptSrc: ["'self'", (req, res) => `'nonce-${res.locals.cspNonce}'`],
      },
    }),
  );

  // app.use(requireHttps);

  // Compression middleware (should be placed before express.static)
  app.use(
    compression({
      threshold: 512,
    }),
  );

  // app.use(
  //   cors({
  //     origin: ['http://localhost:3000', 'https://reboil-demo.herokuapp.com'],
  //     optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
  //     credentials: true,
  //   }),
  // );

  app.use(express.static(path.join(__dirname, '..', 'public')));
  // 访问: `GET /favicon.ico`
  app.use(favicon(path.join(__dirname, '..', 'public', 'favicon32.png')));

  app.use(lessMiddleware(path.join(__dirname, 'public')));
  // view engine setup
  app.set('views', path.join(__dirname, '..', 'views'));
  app.set('view engine', 'ejs');

  app.use(express.urlencoded({ extended: false }));
  app.use(express.json());
  // app.use(bodyParser.urlencoded({ extended: true }));//“bodyParser”已被弃用
  // app.use(bodyParser.json());

  /**
   * 将post请求解析为其他非get请求(string-设置请求头 和 函数-返回特定方法名称)
   */
  app.use(
    methodOverride((req, res) => {
      if (req.body && typeof req.body === 'object' && '_method' in req.body) {
        // look in urlencoded POST bodies and delete it
        const method = req.body.$method;
        delete req.body.$method;
        return method;
      }
      return null;
    }),
  );

  // http 无状态: 客户端会设置cookie,根据设置的connect.sid可以获取对应的session内容
  // 解析Cookie: 因為csrfProtection中的“ cookie”為true
  app.use(cookieParser(process.env.TOKEN_PRIVATE_KEY));
  // `req.session.id === req.sessionID === req.signedCookies['connect.sid']`
  app.use(session({
    name: 'connect.sid', // 此name指的是cookie的name，name默认为：connect.sid
    secret: process.env.TOKEN_PRIVATE_KEY, // 加密key 可以随意书写
    cookie: {
      path: '/',
      signed: true, // 使用签名，类型Boolean，默认为false。`express会使用req.secret来完成签名，需要cookie-parser配合使用` => `req.secret===process.env.TOKEN_PRIVATE_KEY`
      secure: false, // 只能被HTTPS使用
      maxAge: 60 * 1000, // 两次请求的时间差，即超过这个时间再去访问session会失效. 类型为Number
      httpOnly: true, // 只能被web server访问
      // domain：cookie在什么域名下有效，类型为String,。默认为网站域名
      // expires: cookie过期时间，类型为Date。如果没有设置或者设置为0，那么该cookie只在这个这个session有效，即关闭浏览器后，这个cookie会被浏览器删除。
    },
    resave: false, // 是否强制报存session即使没有发生变化
    saveUninitialized: true, // 强制将未初始化的session存储
    // rolling: false, // 每次强制设置cookie时,重置cookie过期时间(默认false)
    // store: new mongoStore({
    //   url: config.db,
    //   collection: 'sessions'
    // }),
  }));

  // use passport session
  app.use(passport.initialize());
  app.use(passport.session());

  // connect flash for flash messages - should be declared after sessions
  // app.use(flash());

  // should be declared after session and flash
  // app.use(helpers(pkg.name));

  // if (env !== 'test') {
  //   app.use(csrf());
  //   // This could be moved to view-helpers :-)
  //   app.use((req, res, next) => {
  //     res.locals.csrf_token = req.csrfToken();
  //     res.locals.paginate = ultimatePagination.getPaginationModel;
  //     next();
  //   });
  // }

  // Object.defineProperty(app.request, 'ip', {
  //   configurable: true,
  //   enumerable: true,
  //   get: function () { return this.get('Client-IP') }
  // })

  // app.use(
  //   expressJwt({
  //     secret: Buffer.from(process.env.TOKEN_PRIVATE_KEY, 'base64'),
  //     algorithms: ['HS256'],
  //     resultProperty: 'locals.user', // 默认是`req.user`->改为`req.locals.user`
  //     credentialsRequired: true, // false：不校验
  //     getToken: function fromHeaderOrQuerystring(req) {
  //       if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
  //         return req.headers.authorization.split(' ')[1];
  //       }
  //       if (req.query && req.query.token) {
  //         return req.query.token;
  //       }
  //       return null;
  //     },
  //   }).unless({
  //     path: ['/captcha', '/register', '/login'],
  //   }),
  // );
};
